package com.douqu.game.core.controller;

import com.bean.core.util.TimeUtils;
import com.bean.core.util.Utils;
import com.douqu.game.core.config.common.CommonData;
import com.douqu.game.core.e.E_ConnectionDestroyType;
import com.douqu.game.core.e.E_PlayerLastUpdate;
import com.douqu.game.core.e.E_PlayerStatus;
import com.douqu.game.core.entity.Player;
import com.douqu.game.core.entity.battle.PlayerBattleData;
import com.douqu.game.core.entity.ext.BoonInfo;
import com.douqu.game.core.entity.ext.data.challenge.HegemonyScoreChangeBean;
import com.douqu.game.core.factory.ConfigFactory;
import com.douqu.game.core.factory.FunctionFactory;
import com.douqu.game.core.netty.NettyConnection;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.protobuf.SGMainProto;
import com.douqu.game.core.protobuf.SGPlayerProto;
import com.douqu.game.core.util.CoreUtils;
import com.douqu.game.core.util.LogUtils;
import com.douqu.game.core.util.SendUtils;

/**
* Created by bean on 2017/7/18.
*/
public class PlayerController {

    /**
     * 服务器规则ID
     */
    private int serverRuleId;
    /**
     * 用户登录的客户端版本
     */
    private String clientVersion;

    /**
     * 是否进了大地图
     */
    private boolean inWorldMap;

    /**
     * 是否处于单人战场
     */
    private boolean isSingleWorldMap;

    private NettyConnection tcpConnection;

    private Player player;

    private PlayerBattleData battleData;

    /**
     * 当前状态
     */
    private E_PlayerStatus status;

    /**
     * 上一次更新数据
     */
    private LastUpdate lastUpdate;

    private String ip;

    /**
     * 大地图战斗缓存数据 -> 任务
     */
    private CommonData[] worldMapTaskCacheData;

    /**
     * 大地图争霸赛分数变化cache
     */
    private HegemonyScoreChangeBean[] hegemonyScoreChangeBeanCache;

    /**
     * 大地图通知玩家信息cache
     */
    private String[] sendMsgCache;

    private boolean[] isHegemonyCache;

    /**
     * 竞技场能挑战的最高名次,在每次打开竞技场的时候取值
     */
    private int arenaChallengeMaxRank;


    public PlayerController(Player player, NettyConnection connection)
    {
        this.player = player;
        this.tcpConnection = connection;
        if(tcpConnection != null)
        {
            this.tcpConnection.setObject(this);
            this.ip = tcpConnection.getIp();
        }

        setStatus(E_PlayerStatus.FREE);
    }

    public void clearBattle()
    {
//        setAttachment(null);
//        setParent(null);
        setStatus(E_PlayerStatus.FREE);
        battleData = null;
    }

    public boolean isOverdue(long currentTime)
    {
        if(lastUpdate == null || lastUpdate.getTime() == 0)
            return false;

        return ConfigFactory.gmSetting.getPlayerOverdueTime() > 0 && currentTime - lastUpdate.getTime() >= ConfigFactory.gmSetting.getPlayerOverdueTime();
    }

    /**
     * 是否在战斗中
     * @return
     */
    public boolean isBattling()
    {
        return status == E_PlayerStatus.BATTLE_ING || status == E_PlayerStatus.BATTLE_WAIT_START;
    }

    public boolean isFree()
    {
        return status == E_PlayerStatus.FREE;
    }




    public void update(long currentMillis)
    {
        if(player.lock)
            return;

        BoonInfo info = player.getExtInfo(BoonInfo.class);
        if(CoreUtils.isFunctionUnLock(FunctionFactory.UNLOCK_LOTTERY, player) && info.getLotteryData().hasRedPointRemind(true, currentMillis) ){
            SendUtils.sendRedPointRemind(this, SGCommonProto.E_RED_POINT_TYPE.RED_POINT_TYPE_LOTTERY);
        }
    }

    public void setLastUpdate(long currentMillis, int code, E_PlayerLastUpdate type)
    {
        if(lastUpdate == null)
            lastUpdate = new LastUpdate(currentMillis, code, type);
        else
        {
            lastUpdate.setTime(currentMillis);
            lastUpdate.setType(type);
            lastUpdate.setCode(code);
        }
    }


//    /**
//     * 发送有改变的物品
//     */
//    public void sendChangeData(int code)
//    {
//        SendUtils.sendFlushData(code, this);
//
//        player.getChangeData().clear();
//    }

    public void updateFC()
    {
        //修改战斗力
        int beforeFC = player.fc;

        int afterFC = player.updateFC();

        if(beforeFC != afterFC)
        {
            player.addChangeGoods(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_OTHER, SGCommonProto.E_GOODS_OTHER_ID.GOODS_OTHER_ID_FC_VALUE, afterFC - beforeFC, afterFC, true);
        }
    }

    /**
     * 发送消息
     * @param msgID
     */
    public void sendMsg(int msgID)
    {
        sendMsg(msgID, null);
    }


    /**
     * 发送消息
     * @param msgID
     * @param data
     */
    public void sendMsg(int msgID, byte[] data)
    {
        if(tcpConnection != null)
        {
            tcpConnection.sendMsg(msgID, data);

            LogUtils.debug(player.getName() + " -> " + tcpConnection.getChannel().remoteAddress() + " 发送消息给客户端：code:"+ SGMainProto.E_MSG_ID.forNumber(msgID) + " 数据长度:" + (data==null?0:data.length));
        }
    }

    public void sendWarn(String key, Object... params)
    {
        if(tcpConnection == null || Utils.isNullOrEmpty(key))
            return;

        LogUtils.debug(player.getName() + " -> " + tcpConnection.getChannel().remoteAddress() + " 发送错误信息给客户端:" + key);

        tcpConnection.sendWarn(key, params);
    }

    public void sendGet(String content)
    {
        if(tcpConnection == null)
            return;

        tcpConnection.sendGet(content);
    }

    public void sendGM(String content)
    {
        if(tcpConnection == null)
            return;

        tcpConnection.sendGM(content);
    }

    public void sendSystem(String content)
    {
        if(tcpConnection == null)
            return;

        tcpConnection.sendSystem(content);
    }

    public void sendOffline()
    {
        if(tcpConnection == null)
            return;

        LogUtils.info("发送离线---->" + player.getName());

        tcpConnection.sendOffline();
    }

    public void sendChat(SGCommonProto.ChatItem chatItem) {
        if(chatItem != null){
            sendMsg(SGMainProto.E_MSG_ID.MSGID_Player_ChatMsg_VALUE, SGPlayerProto.S2C_ChatMsg.newBuilder().
                    setChatItem(chatItem).build().toByteArray());
        }
    }

    public void sendUnknown()
    {
        if(tcpConnection == null)
            return;

        tcpConnection.sendUnknown();
    }


    public void destroy()
    {
        if(tcpConnection != null)
        {
            tcpConnection.destroy();

            tcpConnection = null;
        }
    }

    /**
     * 服务器主动断开
     */
    public void serverDestroy()
    {
        LogUtils.info("服务器主动断开连接:" + tcpConnection);
        if(tcpConnection != null)
        {
            tcpConnection.setDestroyType(E_ConnectionDestroyType.BATTLE_OFFLINE);

            destroy();
        }
    }







    public String getObjectIndex()
    {
        return player.getObjectIndex();
    }

    public String getName()
    {
        return player.getName();
    }


    public E_PlayerStatus getStatus() {
        return status;
    }

    public void setStatus(E_PlayerStatus status)
    {
        this.status = status;
    }



    public Player getPlayer() {
        return player;
    }



    public NettyConnection getTcpConnection() {
        return tcpConnection;
    }

    public void setTcpConnection(NettyConnection tcpConnection) {
        this.tcpConnection = tcpConnection;
    }


    public void setPlayer(Player player) {
        this.player = player;
    }

    public PlayerBattleData getBattleData() {
        return battleData;
    }

    public void setBattleData(PlayerBattleData battleData) {
        this.battleData = battleData;
    }



    public String getIp()
    {
        return ip;
    }

    public CommonData[] getWorldMapTaskCacheData() {
        return worldMapTaskCacheData;
    }

    public void setWorldMapTaskCacheData(CommonData... worldMapTaskCacheData) {
        this.worldMapTaskCacheData = worldMapTaskCacheData;
    }

    public boolean isInWorldMap() {
        return inWorldMap;
    }

    public void setInWorldMap(boolean inWorldMap) {
        this.inWorldMap = inWorldMap;
    }

    public boolean isSingleWorldMap() {
        return isSingleWorldMap;
    }

    public void setSingleWorldMap(boolean isSingleWorldMap) {
        this.isSingleWorldMap = isSingleWorldMap;
    }

    public HegemonyScoreChangeBean[] getHegemonyScoreChangeBeanCache() {
        return hegemonyScoreChangeBeanCache;
    }

    public void setHegemonyScoreChangeBeanCache(HegemonyScoreChangeBean... hegemonyScoreChangeBeanCache) {
        this.hegemonyScoreChangeBeanCache = hegemonyScoreChangeBeanCache;
    }

    public boolean[] getIsHegemonyCache(){
        return isHegemonyCache;
    }

    public void nullIsHegemonyCache(){
        isHegemonyCache = null;
    }

    public void addIsHegemonyCache(boolean... hegemonyCache){
        isHegemonyCache = hegemonyCache;
    }

    public String[] getSendMsgCache() {
        return sendMsgCache;
    }

    public void nullSendMsgCache(){
        sendMsgCache = null;
    }

    public void addSendMsgCache(String... msgCache){
        sendMsgCache = msgCache;
    }

    public int getServerRuleId() {
        return serverRuleId;
    }

    public void setServerRuleId(int serverRuleId) {
        this.serverRuleId = serverRuleId;
    }

    public String getClientVersion() {
        return clientVersion;
    }

    public void setClientVersion(String clientVersion) {
        this.clientVersion = clientVersion;
    }

    public LastUpdate getLastUpdate() {
        return lastUpdate;
    }

    public String showLastUpdateInfo()
    {
        return lastUpdate == null ? "无" : lastUpdate.showInfo();
    }

    public int getArenaChallengeMaxRank() {
        return arenaChallengeMaxRank;
    }

    public void setArenaChallengeMaxRank(int arenaChallengeMaxRank) {
        this.arenaChallengeMaxRank = arenaChallengeMaxRank;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof PlayerController)) return false;

        PlayerController that = (PlayerController) o;

        if (!player.getObjectIndex().equals(that.player.getObjectIndex())) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return player == null ? 0 : player.getObjectIndex().hashCode();
    }


    @Override
    public String toString() {
        return "PlayerController{" +
                "ip='" + ip + '\'' +
                ", player=" + player +
                ", serverRuleId=" + serverRuleId +
                ", clientVersion='" + clientVersion + '\'' +
                ", status=" + status +
                ", lastUpdate=" + lastUpdate +
                '}';
    }
}


class LastUpdate
{
    private long time;

    private int code;

    private E_PlayerLastUpdate type;

    public LastUpdate() {
    }

    public LastUpdate(long time, int code, E_PlayerLastUpdate type)
    {
        this.time = time;
        this.code = code;
        this.type = type;
    }

    public long getTime() {
        return time;
    }

    public void setTime(long time) {
        this.time = time;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        if(code != 0)
            this.code = code;
    }

    public E_PlayerLastUpdate getType() {
        return type;
    }

    public void setType(E_PlayerLastUpdate type) {
        this.type = type;
    }



    public String showInfo()
    {
        return "code->" + (code==0 ? "Null" : SGMainProto.E_MSG_ID.forNumber(code)+"") + ",lastTime->" + TimeUtils.getFormatTime(time) + ",type->" + type.getMsg();
    }

    @Override
    public String toString() {
        return "{" +
                "time=" + TimeUtils.getFormatTime(time) +
                ", code=" + code +
                ", type='" + type + '\'' +
                '}';
    }
}